package com.demo.task.service

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.IntentFilter.SYSTEM_HIGH_PRIORITY
import android.os.Build
import android.os.storage.StorageManager
import android.util.Log
import androidx.lifecycle.LifecycleService
import androidx.lifecycle.lifecycleScope
import com.demo.task.bean.UpdateBean
import com.demo.task.ext.getVersion
import com.google.gson.Gson
import com.simple.device.ApkUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.BufferedReader
import java.io.File
import java.io.FileInputStream
import java.io.InputStreamReader


/**
 * @author  yyk
 * @create  2023-05-18
 */
class UpdateService : LifecycleService() {

    private var onUsbAttached: (() -> Unit)? = null

    private val apkUtils by lazy { ApkUtils()
    }
    override fun onCreate() {
        super.onCreate()


        val filter = IntentFilter()
        filter.addAction("android.intent.action.MEDIA_EJECT")
        filter.addAction("android.intent.action.MEDIA_UNMOUNTED")
        filter.addAction("android.intent.action.MEDIA_REMOVED")
        filter.addAction("android.intent.action.MEDIA_BAD_REMOVAL")
        filter.addAction("android.intent.action.MEDIA_MOUNTED")
        filter.priority = SYSTEM_HIGH_PRIORITY
        filter.addDataScheme("file")

        this.registerReceiver(USBBroadCastReceiver(), filter)


        onUsbAttached = {
            lifecycleScope.launch(Dispatchers.IO) {
                installApk()
            }
        }

        lifecycleScope.launchWhenCreated {
            installApk()
        }
    }

    private fun installApk() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            val storageManager = getSystemService(StorageManager::class.java)
            for (storageVolume in storageManager.storageVolumes) {
                if (storageVolume.isRemovable) {
                    val file = storageVolume.directory
                    file?.listFiles()?.forEach {
                        if (it.name == "Android") {
                            val jsonFile = File("${it.path}/update.json")
                            if (!jsonFile.exists()) {
                                return
                            }

                            val json = jsonFile.readJsonFromInternalStorage()
                            Gson().fromJson(json, UpdateBean::class.java)?.let { bean ->
                                val pathname = "${it.path}/${bean.fileName}"
                                val apkPath = File(pathname)
                                if (!apkPath.exists()) {
                                    return
                                }

                                when {
                                    bean.level == 1 -> {
                                        apkUtils.installApk(apkPath.path)
                                    }

                                    bean.version > getVersion() -> {
                                        apkUtils.installApk(apkPath.path)
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    private fun File.readJsonFromInternalStorage(): String? {
        try {
            val inputStream = FileInputStream(this)
            val bufferedReader = BufferedReader(InputStreamReader(inputStream))
            val stringBuilder = StringBuilder()

            var line: String? = bufferedReader.readLine()
            while (line != null) {
                stringBuilder.append(line).append("\n")
                line = bufferedReader.readLine()
            }
            inputStream.close()

            return stringBuilder.toString()
        } catch (e: Exception) {
            e.printStackTrace()
            return null
        }
    }


    inner class USBBroadCastReceiver : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            Log.i(TAG, "onReceive: ${intent?.action}")
            when (intent?.action) {
                Intent.ACTION_MEDIA_UNMOUNTED -> {
                    Log.i(TAG, "onReceive: MEDIA_UNMOUNTED")
                }

                Intent.ACTION_MEDIA_MOUNTED -> {
                    onUsbAttached?.invoke()
                    Log.i(TAG, "onReceive: MEDIA_MOUNTED")
                }
            }
        }
    }


    companion object {
        private const val TAG = "UpdateService"

        fun Context.startUpdateService() {
            val intent = Intent(this, UpdateService::class.java)
            startService(intent)
        }
    }
}